from flask import Blueprint, current_app, jsonify, session, request
from sqlalchemy.exc import IntegrityError
from app.utils.code import RET
from app.utils.common import login_required
from app.utils.util import md5, create_password, create_nonce_str
from app.models import UserModel, HouseModel, OrderModel
from app import db
import os
import re

api_user = Blueprint("api_user", __name__)

''' 判断是否登录 '''
@api_user.route('/session', methods=["GET"])
def check_session():
    # 判断是否登录
    if "user_id" in session:
        user_id = session['user_id']
        if user_id is not None:
            return jsonify(errno = RET.OK, errmsg = "已经登录", data={"name": session['name'] if session['name'] is not None else session['mobile']})
    return jsonify(errno = RET.LOGINERR, errmsg = "用户未登录")

''' 获取用户信息 '''
@api_user.route("/user", methods=["GET"])
@login_required
def get_user():
    try:
        user = UserModel.query.filter_by(id=session['user_id']).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")
    
    if not all([user.real_name, user.id_card]):
        return jsonify(errno=RET.AUTHERR, errmsg="用户未实名")
    return jsonify(errno=RET.OK, data={"name": user.nickname, "mobile":user.mobile, "avatar":user.avatar_url, "id_card": user.id_card, "real_name": user.real_name})

''' 用户认证 '''
@api_user.route("/user/auth", methods=["GET", "POST"])
@login_required
def get_auth():
    try:
        user = UserModel.query.filter_by(id=session['user_id']).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")
    
    if request.method == "GET":
        return jsonify(errno=RET.OK, data={"real_name":user.real_name, "id_card": user.id_card})
    elif request.method == "POST":
        json_dict = request.get_json()
        user.real_name = json_dict.get('real_name')
        user.id_card = json_dict.get('id_card')
        try:
            db.session.add(user)
            db.session.commit()
            return jsonify(errno=RET.OK, errmsg="修改成功")
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="修改失败")

''' 修改头像 '''
@api_user.route("/user/avatar", methods=["POST"])
@login_required
def set_avatar():
    files = request.files
    if "avatar" not in files:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    file = files.get("avatar")
    name, ext = file.filename.split(".")
    img = "/static/upload/" + md5(name) + "." + ext
    try:
        file.save(os.path.dirname(__file__) + "/.." + img)
        user = UserModel.query.filter_by(id=session['user_id']).first()
        user.avatar_url = img
        db.session.add(user)
        db.session.commit()
        return jsonify(errno=RET.OK, errmsg="上传成功", data={"avatar_url": img})
    except Exception as e:
        db.session.rollback()
        return jsonify(errno=RET.PARAMERR, errmsg="上传失败")

''' 修改名称 '''
@api_user.route("/user/name", methods=["PUT"])
@login_required
def set_nickname():
    json_dict = request.get_json()
    nickname = json_dict.get('name')
    # 判断是否已经存在
    count = UserModel.query.filter_by(nickname=nickname).count()
    if count:
        return jsonify(errno=RET.DATAEXIST, errmsg="用户名已经存在")
    
    user = UserModel.query.filter_by(id=session['user_id']).first()
    user.nickname = nickname
    try:
        db.session.add(user)
        db.session.commit()
        return jsonify(errno=RET.OK, errmsg="修改成功")
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="修改失败")

''' 客户与房东订单列表信息 '''
@api_user.route("/user/orders", methods=["GET"])
@login_required
def get_user_orders():
    role = request.args.get("role", "")
    user_id = session['user_id']
    try:
        # 房东
        if role == "landlord":
            # 获取房东发布的所有房源
            houses = HouseModel.query.filter_by(user_id=user_id, is_deleted=0).all()
            house_ids = [house.id for house in houses]
            # 获取房源下的所有订单
            orders = OrderModel.query.filter(OrderModel.house_id.in_(house_ids)).order_by(OrderModel.id.desc()).all()
        else:
            # 用户
            orders = OrderModel.query.filter(OrderModel.user_id==user_id).order_by(OrderModel.id.desc()).all()
            pass
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询订单信息失败")
    orders_dict = []
    for order in orders:
        orders_dict.append(order.to_json())
    return jsonify(errno=RET.OK, errmsg="获取成功", data={"orders": orders_dict})

''' 注册 '''
@api_user.route('/register', methods = ["POST"])
def register():
    json_dict = request.get_json()
    mobile = json_dict.get('mobile', "")
    sms_code = json_dict.get('sms_code', "")
    password = json_dict.get('password', "")
    password2 = json_dict.get('password2', "")

    # 判断参数是否完整
    if not all([mobile, sms_code, password, password2]):
        return jsonify(errno = RET.PARAMERR, errmsg = "参数错误")
    
    if not re.match(r"1[34578]\d{9}", mobile):
        return jsonify(errno = RET.PARAMERR, errmsg = "手机号格式错误")

    if password != password2:
        return jsonify(errno = RET.PARAMERR, errmsg = "两次密码不一致")
    
    if session['sms_code_' + mobile] != sms_code:
        return jsonify(errno = RET.PARAMERR, errmsg = "手机验证码不正确")
    
    # 设置用户信息
    salt = create_nonce_str()
    pwd = create_password(password, salt)
    user = UserModel(mobile=mobile, password=pwd, salt=salt)
    try:
        db.session.add(user)
        db.session.commit()
    except IntegrityError as e:
        # 数据库操作错误后的回滚
        db.session.rollback()
        # 表示手机号出现了重复值，即手机号已注册过
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAEXIST, errmsg="手机号已存在")
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR, errmsg = "查询数据库异常")
    
    # 注册成功后，保存会话信息
    session['user_id'] = user.id
    session['name'] = mobile
    session['mobile'] = mobile
    return jsonify(errno = RET.OK, errmsg = "注册成功")

''' 登录 '''
@api_user.route("/login", methods=["POST"])
def login():
    json_dict = request.get_json()
    mobile = json_dict.get('mobile')
    password = json_dict.get('password')

    if not all([mobile, password]):
        return jsonify(errno = RET.PARAMERR, errmsg = "参数错误")
    
    if not re.match(r"1[34578]\d{9}", mobile):
        return jsonify(errno = RET.PARAMERR, errmsg = "手机号格式错误")
    
    try:
        user = UserModel.query.filter_by(mobile=mobile).first()
    except Exception as e:
        return jsonify(errno=RET.DBERR, errmsg = "查询数据库异常")
    
    if user is None:
        return jsonify(errno = RET.DATANOTEXIST, errmsg = "手机号不存在")
    
    if create_password(password, user.salt) != user.password:
        return jsonify(errno = RET.PARAMERR, errmsg = "手机号或密码错误")
    
    session['user_id'] = user.id
    session['name'] = user.nickname
    session['mobile'] = mobile
    return jsonify(errno = RET.OK, errmsg = "登录成功")

''' 退出登录 '''
@api_user.route("/logout", methods=["DELETE"])
@login_required
def logout():
    del session['user_id']
    del session['name']
    del session['mobile']
    return jsonify(errno = RET.OK, errmsg = "退出成功")